package com.xunwulian.web.controller.frame;

import com.alibaba.dubbo.config.annotation.Reference;
import com.xunwulian.api.iface.MenuAPI;
import com.xunwulian.api.iface.RoleAPI;
import com.xunwulian.api.iface.UserAPI;
import com.xunwulian.base.constant.OperationType;
import com.xunwulian.base.dao.RoleDao;
import com.xunwulian.base.entity.*;
import com.xunwulian.base.util.PageData;
import com.xunwulian.base.util.SysUtils;
import com.xunwulian.web.controller.BaseController;
import com.xunwulian.web.util.AppUtil;
import com.xunwulian.web.util.Const;
import com.xunwulian.web.util.JurisdictionHelper;
import com.xunwulian.web.util.RightsHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping(value = "/role")
public class RoleController extends BaseController {

    String menuUrl = "role.do"; // 菜单地址(权限用)

    @Reference
    private UserAPI userAPI;
    @Reference
    private RoleAPI roleAPI;
    @Reference
    private MenuAPI menuAPI;

    @Autowired
    private RoleDao roleDao;

    /**
     * 更新增删改查权限
     */
    @RequestMapping(value = {"/qx", "/kfqx", "/gysqxc"})
    public ModelAndView qx() {
        ModelAndView mv = this.getModelAndView();
        PageData pd = this.getPageData();
        try {
            if (JurisdictionHelper.buttonJurisdiction(menuUrl, OperationType.EDIT.role)) {
                // 权限操作类型：增删改查
                String operation = pd.getString("msg");
                String value = pd.getString("value");
                String roleId = pd.getString("ROLE_ID");
                roleAPI.updateQX(operation, value, roleId);
            }
            mv.setViewName("save_result");
            mv.addObject("msg", "success");
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        return mv;
    }

    /**
     * 权限列表
     */
    @RequestMapping
    public ModelAndView list(Page page) {
        ModelAndView mv = this.getModelAndView();
        PageData pd = this.getPageData();

        String roleId = pd.getString("ROLE_ID");
        if (StringUtils.isBlank(roleId)) {
            roleId = "1";
        }
        // 列出所有部门
        List<Role> roleList = roleDao.listAllRoles();

        // 列出此部门的所有下级
        List<Role> roleList_z = roleDao.listAllRolesByPId(roleId);

        List<GLQXEntity> kefuqxlist = roleDao.listAllkefu(); // 管理权限列表
        List<HYQXEntity> gysqxlist = roleDao.listAllGysQX(); // 用户权限列表

        Role role = roleDao.findById(roleId);

        mv.addObject("roleId", role.getROLE_ID());
        mv.addObject("roleName", role.getROLE_NAME());
        mv.addObject("kefuqxlist", kefuqxlist);
        mv.addObject("gysqxlist", gysqxlist);
        mv.addObject("roleList", roleList);
        mv.addObject("roleList_z", roleList_z);

        mv.setViewName("system/role/role_list");
        mv.addObject(Const.SESSION_QX, this.getHC()); // 按钮权限

        return mv;
    }

    /**
     * 新增页面
     *
     * @param page
     * @return
     */
    @RequestMapping(value = "/toAdd")
    public ModelAndView toAdd(Page page) {
        ModelAndView mv = this.getModelAndView();
        PageData pd = this.getPageData();
        try {
            mv.setViewName("system/role/role_add");
            mv.addObject("pd", pd);
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        return mv;
    }

    /**
     * 保存新增信息
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public ModelAndView add() {
        ModelAndView mv = this.getModelAndView();
        PageData pd = this.getPageData();
        String parent_id = pd.getString("PARENT_ID"); // 父类角色id

        try {
            String rights = "";
            if (!"0".equals(parent_id)) {
                rights = roleDao.findById(parent_id).getRIGHTS();
            }

            String UUID = this.get32UUID();

            // 保存到K权限表
            GLQXEntity glqx = new GLQXEntity(UUID, parent_id);
            if (JurisdictionHelper.buttonJurisdiction(menuUrl, OperationType.ADD.role)) {
                roleDao.saveKeFu(glqx);
            }

            // 保存到hy权限表
            HYQXEntity hyqx = new HYQXEntity(UUID);
            if (JurisdictionHelper.buttonJurisdiction(menuUrl, OperationType.ADD.role)) {
                roleDao.saveGYSQX(hyqx);
            }

            // 保存到G权限表
            Role role = new Role(UUID, "", rights, parent_id, UUID);
            if (JurisdictionHelper.buttonJurisdiction(menuUrl, OperationType.ADD.role)) {
                roleDao.insert(role);
            }

            mv.addObject("msg", "success");
        } catch (Exception e) {
            logger.error(e.toString(), e);
            mv.addObject("msg", "failed");
        }
        mv.setViewName("save_result");
        return mv;
    }

    /**
     * 跳转到编辑角色名称的页面
     */
    @RequestMapping(value = "/toEdit")
    public ModelAndView toEdit(String ROLE_ID) {
        ModelAndView mv = this.getModelAndView();
        try {
            Role role = roleDao.findById(ROLE_ID);
            mv.setViewName("system/role/role_edit");
            mv.addObject("roleId", role.getROLE_ID());
            mv.addObject("roleName", role.getROLE_NAME());
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        return mv;
    }

    /**
     * 编辑更新角色名称
     */
    @RequestMapping(value = "/edit")
    public ModelAndView edit() {
        ModelAndView mv = this.getModelAndView();
        PageData pd = this.getPageData();
        String roleName = pd.getString("ROLE_NAME");
        String roleId = pd.getString("ROLE_ID");
        try {
            if (JurisdictionHelper.buttonJurisdiction(menuUrl, OperationType.EDIT.role)) {
                roleDao.updateName(roleName, roleId);
            }
            mv.addObject("msg", "success");
        } catch (Exception e) {
            logger.error(e.toString(), e);
            mv.addObject("msg", "failed");
        }
        mv.setViewName("save_result");
        return mv;
    }

    /**
     * 请求角色菜单授权页面
     */
    @RequestMapping(value = "/auth")
    public String auth(@RequestParam String ROLE_ID, Model model) {
        try {
            List<Menu> menuList = menuAPI.listAllMenu();
            Role role = roleDao.getRoleById(ROLE_ID);
            String roleRights = role.getRIGHTS();

            RightsHelper.updateMenuRights(roleRights, menuList);

            JSONArray arr = new JSONArray(menuList);
            String json = arr.toString();
            json = json.replaceAll("MENU_ID", "id")
                    .replaceAll("MENU_NAME", "name")
                    .replaceAll("subMenu", "nodes")
                    .replaceAll("hasMenu", "checked");
            model.addAttribute("zTreeNodes", json);
            model.addAttribute("roleId", ROLE_ID);
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }

        return "authorization";
    }

    /**
     * 跳转到角色菜单设置页面
     */
    @RequestMapping(value = "/button")
    public ModelAndView button(@RequestParam String ROLE_ID,
                               @RequestParam("msg") String operation, Model model) {
        ModelAndView mv = this.getModelAndView();
        try {
            List<Menu> menuList = menuAPI.listAllMenu();
            Role role = roleDao.getRoleById(ROLE_ID);

            String roleRights = "";
            if ("add_qx".equals(operation)) {
                roleRights = role.getADD_QX();
            } else if ("del_qx".equals(operation)) {
                roleRights = role.getDEL_QX();
            } else if ("edit_qx".equals(operation)) {
                roleRights = role.getEDIT_QX();
            } else if ("cha_qx".equals(operation)) {
                roleRights = role.getCHA_QX();
            }

            RightsHelper.updateMenuRights(roleRights, menuList);

            JSONArray arr = new JSONArray(menuList);
            String json = arr.toString();
            logger.info("请求角色按钮授权页面，" + json);
            json = json.replaceAll("MENU_ID", "id")
                    .replaceAll("MENU_NAME", "name")
                    .replaceAll("subMenu", "nodes")
                    .replaceAll("hasMenu", "checked");
            mv.addObject("zTreeNodes", json);
            mv.addObject("roleId", ROLE_ID);
            mv.addObject("msg", operation);
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        mv.setViewName("system/role/role_button");
        return mv;
    }


    /**
     * 保存角色菜单权限
     *
     */
    @RequestMapping(value = "/auth/save")
    public void saveAuth(@RequestParam String ROLE_ID,
                         @RequestParam String menuIds, PrintWriter out) {
        PageData pd = new PageData();
        try {
            if (JurisdictionHelper.buttonJurisdiction(menuUrl, OperationType.EDIT.role)) {
                if (StringUtils.isNotBlank(menuIds)) {
                    BigInteger rights = RightsHelper.sumRights(SysUtils
                            .str2StrArray(menuIds));
                    roleDao.updateRoleRights(rights.toString(), ROLE_ID);
                    pd.put("rights", rights.toString());
                } else {
                    roleDao.updateRoleRights("", ROLE_ID);
                    pd.put("rights", "");
                }

                pd.put("roleId", ROLE_ID);
                String rights = pd.getString("rights");
                roleDao.setAllRights(ROLE_ID, rights);
            }
            out.write("success");
            out.close();
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
    }

    /**
     * 保存角色按钮权限
     *
     */
    @RequestMapping(value = "/roleButton/save")
    public void orleButton(@RequestParam String ROLE_ID,
                           @RequestParam String menuIds, @RequestParam String msg,
                           PrintWriter out) {
        try {
            if (JurisdictionHelper.buttonJurisdiction(menuUrl, OperationType.EDIT.role)) {
                String value = "";
                if (StringUtils.isNotBlank(menuIds)) {
                    BigInteger rights = RightsHelper.sumRights(SysUtils.str2StrArray(menuIds));
                    value = rights.toString();
                }
                roleAPI.updateQX(msg, value, ROLE_ID);
            }
            out.write("success");
            out.close();
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
    }

    /**
     * 删除
     */
    @RequestMapping(value = "/delete")
    @ResponseBody
    public Object deleteRole(@RequestParam String ROLE_ID) {
        Map<String, String> map = new HashMap<String, String>();
        PageData pd = new PageData();
        String errInfo = "";
        try {
            if (JurisdictionHelper.buttonJurisdiction(menuUrl, OperationType.DEL.role)) {
                pd.put("ROLE_ID", ROLE_ID);
                // 列出此部门的所有下级
                List<Role> roleList_z = roleDao.listAllRolesByPId(ROLE_ID);
                if (roleList_z.size() > 0) {
                    errInfo = "false";
                } else {
                    if (userAPI.countByRoleId(ROLE_ID) > 0) {
                        errInfo = "false2";
                    } else {
                        roleDao.deleteRoleById(ROLE_ID);
                        roleDao.deleteKeFuById(ROLE_ID);
                        roleDao.deleteGById(ROLE_ID);
                        errInfo = "success";
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        map.put("result", errInfo);
        return AppUtil.returnObject(new PageData(), map);
    }

    /**
     * @return
     */
    public Map<String, String> getHC() {
        Subject currentUser = SecurityUtils.getSubject(); // shiro管理的session
        Session session = currentUser.getSession();
        return (Map<String, String>) session.getAttribute(Const.SESSION_QX);
    }

}
